#!/usr/bin/env python
import tempfile
from subprocess import *
import sys
import os
import re
import BugleChecks

Import('envs', 'aspects', 'targets', 'libraries', 'srcdir')

def simple_test(name):
    return test_env.Program(
            target = name,
            source = [name + '.c'])

def add_test_target(env, test, test_deps):
    env.Depends(test, test_deps)
    env.Depends(test, '../filters')
    env.AlwaysBuild(test)
    env.Alias('test', test)

if 'tests' not in aspects['parts']:
    Return()

test_env = envs['host'].Clone()
test_deps = []
test_sources = ['test.c', 'string.c', 'math.c', 'threads.c']
bugle_path = os.path.dirname(targets['bugleutils'].out[0].abspath)
filter_dir = os.path.join(bugle_path, 'filters')
filters = srcdir.File('filters').abspath

if 'interceptor' not in aspects['parts']:
    print 'WARNING: cannot run some tests without interceptor. They will be skipped'
else:
    if aspects['gltype'] == 'gl':
        glew_lib = False
        glut_lib = False
        glu_lib = False

        conf = Configure(test_env, custom_tests = BugleChecks.tests)
        if conf.CheckLibWithHeader('GLEW', 'GL/glew.h', 'c', autoadd = False):
            glew_lib = 'GLEW'
        elif conf.CheckLibWithHeader('glew32', 'GL/glew.h', 'c', autoadd = False):
            glew_lib = 'glew32'
        if conf.CheckLibWithHeader('glut', 'GL/glut.h', 'c', autoadd = False):
            glut_lib = 'glut'
        elif conf.CheckLibWithHeader('glut32', 'GL/glut.h', 'c', autoadd = False):
            glut_lib = 'glut32'
        elif conf.CheckLibWithHeader('freeglut', 'GL/glut.h', 'c', autoadd = False):
            glut_lib = 'freeglut'
        if conf.CheckLibWithHeader('GLU', ['GL/glut.h', 'GL/glu.h'], 'c', autoadd = False):
            glu_lib = 'GLU'
        elif conf.CheckLibWithHeader('glu32', ['GL/glut.h', 'GL/glu.h'], 'c', autoadd = False):
            glu_lib = 'GLU32'

        have_freeglut = conf.CheckCHeader('GL/freeglut.h')
        use_gl = glew_lib and glut_lib and glu_lib
        if use_gl:
            conf.env.Append(LIBS = [glew_lib, glut_lib, glu_lib])
            test_env = conf.Finish()

            test_env.Append(LIBS = libraries)
            # libdl should be pulled in by dependencies, but since the dlopen
            # test calls it directly we will explicitly list it. This is apparently
            # needed due to some symbol version weirdness on Fedora 14 (bug #84).
            if aspects['platform'] == 'posix':
                test_env.Append(LIBS = ['dl'])
            # The ARB_create_context GLX test calls X11 directly instead of using GLUT
            if aspects['glwin'] == 'glx':
                test_env.Append(LIBS = ['X11'])
            test_env.Append(CPPDEFINES = ['TEST_GL'])
            if have_freeglut:
                test_env.Append(CPPDEFINES = ['HAVE_GL_FREEGLUT_H'])

            test_deps.append(targets['bugle'].out)
            test_sources.extend([
                'errors.c',
                'interpose.c',
                'procaddress.c',
                'dlopen.c',
                'draw.c',
                'extoverride.c',
                'logdebug.c',
                'pbo.c',
                'pointers.c',
                'queries.c',
                'setstate.c',
                'showextensions.c',
                'texcomplete.c',
                'triangles.c'
                ])
            if aspects['glwin'] == 'glx':
                test_sources.extend([
                    'arbcreatecontext.c',
                    'contextattribs.c'
                    ])

            # Standalone tests that are not part of the test suite
            simple_test('objects')
            simple_test('shadertest')
            simple_test('textest')
            if aspects['glwin'] == 'glx':
                simple_test('threads1')
                simple_test('threads2')
        else:
            print 'WARNING: GLEW, GLUT and GLU are required for some tests'
    else:
        print 'WARNING: not all tests run on this variant of OpenGL'

bugletest = test_env.Program(
        target = 'bugletest',
        source = test_sources + targets['bugleutils'].out)
test_deps.append(bugletest)

paths = {
        'LIBRARY_PATH': bugle_path,
        'FILTER_DIR': filter_dir,
        'FILTERS': filters,
        'TESTER': bugletest[0].abspath
        }
options = test_env.SubstFile('options.txt', 'options.txt.in', paths)
# Windows needs the bugle wrapper library to be in the same directory as
# the executable.
if aspects['binfmt'] == 'pe':
    trg = targets['bugle'].out[0]
    filename = os.path.basename(trg.path)
    test_env.CopyAs(filename, trg)

test_deps.append(options)

test = test_env.Command(Value(''), ['bugletest.py', options],
        Action('python ${SOURCES[0].path} @${SOURCES[1].path}', 'Running tests'))
add_test_target(test_env, test, test_deps)
